package cn.edu.xmu.oomall.payment.dao;

import cn.edu.xmu.oomall.core.util.ReturnNo;
import cn.edu.xmu.oomall.core.util.ReturnObject;
import cn.edu.xmu.oomall.payment.mapper.PaymentPatternPoMapper;
import cn.edu.xmu.oomall.payment.mapper.PaymentPoMapper;
import cn.edu.xmu.oomall.payment.model.bo.Payment;
import cn.edu.xmu.oomall.payment.model.bo.PaymentPattern;
import cn.edu.xmu.oomall.payment.model.po.PaymentPatternPo;
import cn.edu.xmu.oomall.payment.model.po.PaymentPatternPoExample;
import cn.edu.xmu.oomall.payment.model.po.PaymentPo;
import cn.edu.xmu.oomall.payment.model.po.PaymentPoExample;
import cn.edu.xmu.oomall.payment.model.vo.AllPaymentPatternsVo;
import cn.edu.xmu.oomall.payment.model.vo.OrderPaymentVo;
import cn.edu.xmu.oomall.payment.model.vo.PatternRetVo;
import cn.edu.xmu.privilegegateway.annotation.util.Common;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static cn.edu.xmu.privilegegateway.annotation.util.Common.cloneVo;

@Repository
public class PaymentDao {
    @Autowired
    private PaymentPoMapper paymentPoMapper;
    @Autowired
    private PaymentPatternPoMapper paymentPatternPoMapper;

    /**
     * 增加支付单
     */
    public ReturnObject insertPayment(Payment payment){
        PaymentPo paymentPo=Common.cloneVo(payment,PaymentPo.class);
        try{
            int ret=paymentPoMapper.insert(paymentPo);
            if(ret==0){
                return new ReturnObject(ReturnNo.FIELD_NOTVALID);
            }
            return new ReturnObject(paymentPo);
        }catch (Exception e){
            return new ReturnObject(ReturnNo.INTERNAL_SERVER_ERR);
        }
    }

    /**
     * 修改
     */
    public ReturnObject updatePayment(Payment payment){
        PaymentPo paymentPo=Common.cloneVo(payment,PaymentPo.class);
        try{
            int ret=paymentPoMapper.updateByPrimaryKey(paymentPo);
            if(ret==0){
                return new ReturnObject(ReturnNo.FIELD_NOTVALID);
            }
            return new ReturnObject(ReturnNo.OK);
        }catch (Exception e){
            return new ReturnObject(ReturnNo.INTERNAL_SERVER_ERR);
        }
    }

    /**
     * 删除支付单
     */
    public ReturnObject deletePayment(Long id){
        try{
            int ret=paymentPoMapper.deleteByPrimaryKey(id);
            if(ret==0){
                return new ReturnObject(ReturnNo.FIELD_NOTVALID);
            }
            return new ReturnObject(ReturnNo.OK);
        } catch (Exception e){
            return new ReturnObject(ReturnNo.INTERNAL_SERVER_ERR);
        }
    }

    /**
     * 根据支付交易流水号查看支付单
     */
    public ReturnObject selectPaymentByTradeSn(String tradeSn){
        PaymentPoExample example=new PaymentPoExample();
        PaymentPoExample.Criteria criteria=example.createCriteria();
        criteria.andTradeSnEqualTo(tradeSn);
        try{
            List<PaymentPo> paymentPos=paymentPoMapper.selectByExample(example);
            PaymentPo po;
            if(paymentPos.size()==0){
                return new ReturnObject();
            } else{
                po=paymentPos.get(0);
            }
            return new ReturnObject(Common.cloneVo(po,Payment.class));
        } catch (Exception e){
            return new ReturnObject(ReturnNo.INTERNAL_SERVER_ERR);
        }
    }


    /**
     * 根据时间间隔查看支付单
     */
    public ReturnObject selectPaymentByTime(LocalDateTime beginTime,LocalDateTime endTime){
        PaymentPoExample example=new PaymentPoExample();
        PaymentPoExample.Criteria criteria=example.createCriteria();
        criteria.andPayTimeBetween(beginTime,endTime);
        try{
            List<PaymentPo> paymentPos=paymentPoMapper.selectByExample(example);
            List<Payment> payments=new ArrayList<>(paymentPos.size());
            for(PaymentPo paymentPo:paymentPos){
                Payment payment=Common.cloneVo(paymentPo,Payment.class);
                payments.add(payment);
            }
            return new ReturnObject(payments);
        } catch (Exception e){
            return new ReturnObject(ReturnNo.INTERNAL_SERVER_ERR);
        }
    }

    /**
     * 根据id查看支付单
     */
    public ReturnObject selectPaymentById(Long id){
        try{
            PaymentPo paymentPo=paymentPoMapper.selectByPrimaryKey(id);
            return new ReturnObject(Common.cloneVo(paymentPo,Payment.class));
        } catch (Exception e){
            return new ReturnObject(ReturnNo.INTERNAL_SERVER_ERR);
        }
    }

    /**
     * 查询自己订单的支付信息
     * @param paymentPoExample
     * @return ReturnObject
     */
    public ReturnObject getOrderPayments(PaymentPoExample paymentPoExample) {
        try {
            List<PaymentPo> paymentPos = paymentPoMapper.selectByExample(paymentPoExample);
            List<OrderPaymentVo> orderPaymentVos = new ArrayList<>();
            for(PaymentPo paymentPo:paymentPos) {
                orderPaymentVos.add(cloneVo(paymentPo, OrderPaymentVo.class));
            }
            return new ReturnObject(orderPaymentVos);
        }
        catch (Exception e) {
            e.printStackTrace();
            return new ReturnObject<>(ReturnNo.INTERNAL_SERVER_ERR);
        }
    }

    /**
     * 获得支付渠道的所有状态
     * @return ReturnObject
     */
    public ReturnObject getAllPatternStates() {
        try {
            List<Map<String, Object>> stateList = new ArrayList<>();
            for (PaymentPattern.State states : PaymentPattern.State.values()) {
                Map<String, Object> temp = new HashMap<>();
                temp.put("code", states.getCode());
                temp.put("name", states.getDescription());
                stateList.add(temp);
            }
            return new ReturnObject<>(stateList);
        }
        catch (Exception e) {
            return new ReturnObject<>(ReturnNo.INTERNAL_SERVER_ERR);
        }
    }

    /**
     * 获得支付单的所有状态
     * @return ReturnObject
     */
    public ReturnObject getAllPaymentsStates() {
        try {
            List<Map<String,Object>> stateList = new ArrayList<>();
            for(Payment.State states: Payment.State.values()) {
                Map<String,Object> temp = new HashMap<>();
                temp.put("code",states.getCode());
                temp.put("name",states.getDescription());
                stateList.add(temp);
            }

            return new ReturnObject<>(stateList);

        }
        catch (Exception e) {
            return new ReturnObject<>(ReturnNo.INTERNAL_SERVER_ERR);
        }
    }

    /**
     * 获得所有的支付渠道
     * @param paymentPoExample
     * @return ReturnObject
     */
    public ReturnObject getPayPatterns(PaymentPoExample paymentPoExample) {
        try {
            List<PaymentPo> paymentPos = paymentPoMapper.selectByExample(paymentPoExample);
            List<AllPaymentPatternsVo> allPaymentPatternsVos = new ArrayList<>();

            for(PaymentPo paymentPo:paymentPos)
            {
                allPaymentPatternsVos.add(cloneVo(paymentPo,AllPaymentPatternsVo.class));
            }

            return new ReturnObject(allPaymentPatternsVos);
        }
        catch (Exception e) {
            e.printStackTrace();
            return new ReturnObject<>(ReturnNo.INTERNAL_SERVER_ERR);
        }
    }

    /**
     * 获得当前有效的支付渠道
     * @param paymentPatternPoExample
     * @return ReturnObject
     */
    public ReturnObject getAvailablePatterns(PaymentPatternPoExample paymentPatternPoExample) {
        try {
            List<PaymentPatternPo> paymentPatternPos = paymentPatternPoMapper.selectByExample(paymentPatternPoExample);
            List<PatternRetVo> patternRetVos = new ArrayList<>();

            for(PaymentPatternPo paymentPatternPo:paymentPatternPos) {
                patternRetVos.add(cloneVo(patternRetVos,PatternRetVo.class));
            }

            return new ReturnObject(patternRetVos);

        }
        catch (Exception e) {
            e.printStackTrace();
            return new ReturnObject(ReturnNo.INTERNAL_SERVER_ERR);
        }
    }
}
